Skip to content

Build Linux dynamic libraries with cross for older glibc compatibility - #1214

Draft
twyatt wants to merge 2 commits into
mainfrom
cursor/linux-glibc-cross-build-7b6a
Draft

Build Linux dynamic libraries with cross for older glibc compatibility#1214
twyatt wants to merge 2 commits into
mainfrom
cursor/linux-glibc-cross-build-7b6a

Conversation

@twyatt

@twyatt twyatt commented Jul 15, 2026

Copy link
Copy Markdown
Member

Resolves #990

Problem

The Linux kable-btleplug-ffi dynamic libraries are built directly on GitHub's Ubuntu runners, so they link against the runner's glibc (2.38+). On distributions with an older glibc (e.g. Raspberry Pi OS, glibc ≤ 2.36), JNA fails to load the library and Sensortag scans crash immediately.

Solution

As suggested in the issue, Linux builds now go through cross, using its CentOS 7 based images (main-centos tags, pinned via kable-btleplug-ffi/Cross.toml) so the produced .so files link against glibc 2.17.

Note

The issue mentions cross's default toolchain being on glibc 2.31, but cross's default images have since moved to Ubuntu 24.04 (glibc 2.39), which would reproduce the original problem — hence the CentOS 7 images, which the issue also mentions as an option.

uniffi-plugin

  • New optional cargoCommand extension property: command used to build the dynamic library (defaults to cargo). CI sets it to cross for Linux builds via the UNIFFI_CARGO environment variable.
  • New optional target extension property: Rust target triple to build the dynamic library for (defaults to the host's target). CI sets it via the UNIFFI_TARGET environment variable. This was needed because cross does not publish arm64 host images (cross-rs/cross#751), so the aarch64-unknown-linux-gnu library is now cross-compiled from the x86_64 runner instead of being built natively on ubuntu-24.04-arm.
  • generateKotlinBindings still runs uniffi-bindgen with host cargo; only the --library it parses points at the (possibly cross-compiled) target library, which works since uniffi-bindgen reads metadata from the binary statically.

Workflows (ci.yml / publish.yml)

  • The assemble-rust matrix replaces the ubuntu-24.04-arm + ubuntu-latest runners with two ubuntu-latest entries (one per Linux target) that install cross (from git main, matching the pinned main-centos image tags) and export UNIFFI_CARGO/UNIFFI_TARGET.
  • Linux artifact names are now keyed by target triple instead of runner name; macOS/Windows artifacts are unchanged.

Local (non-CI) builds are unaffected: without the environment variables set, the plugin behaves exactly as before (cargo build --target <host triple>).

Verification

Performed locally (Docker + cross installed from git main, same as CI):

  • UNIFFI_CARGO=cross UNIFFI_TARGET=aarch64-unknown-linux-gnu ./gradlew :kable-btleplug-ffi:assemble → jar contains linux-aarch64/libbtleplug_ffi.so, objdump -T shows max versioned symbol GLIBC_2.17.
  • UNIFFI_CARGO=cross ./gradlew :kable-btleplug-ffi:cargoBuild (x86_64) → max versioned symbol GLIBC_2.16.
  • Plain ./gradlew :kable-btleplug-ffi:assemble (no env vars) → unchanged native host build.
Open in Web Open in Cursor 

cursoragent and others added 2 commits July 15, 2026 22:13
Allows building the dynamic library for a Rust target other than the
host's (e.g. cross-compiling aarch64-unknown-linux-gnu from an x86_64
host) and building with a cargo-compatible command such as cross
(https://github.com/cross-rs/cross).

Co-authored-by: Travis Wyatt <travis.i.wyatt@gmail.com>
GitHub's Ubuntu runners link against a glibc newer than what is
available on some Linux distributions (e.g. Raspberry Pi OS), causing
JNA to fail to load kable-btleplug-ffi at runtime. Build the Linux
dynamic libraries with cross (https://github.com/cross-rs/cross) using
its CentOS 7 based images so they link against glibc 2.17, and
cross-compile the aarch64 library from the x86_64 runner (cross does
not publish arm64 host images).

Resolves: #990

Co-authored-by: Travis Wyatt <travis.i.wyatt@gmail.com>
@twyatt twyatt added the jvm label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix linked glibc version in Linux (JVM) builds

2 participants